package cn.lingyangwl.agile.pay.pay.channel.wxpay;

import cn.lingyangwl.agile.pay.pay.channel.wxpay.utils.WxpayKit;
import cn.lingyangwl.agile.pay.pay.channel.wxpay.utils.WxpayV3Util;
import cn.lingyangwl.framework.tool.core.exception.BizException;
import cn.lingyangwl.agile.pay.constant.IfCodeEnum;
import cn.lingyangwl.agile.pay.model.rqrs.pay.refund.RefundOrderRQ;
import cn.lingyangwl.agile.pay.model.entity.PayOrder;
import cn.lingyangwl.agile.pay.model.entity.RefundOrder;
import cn.lingyangwl.agile.pay.common.constants.Cs;
import cn.lingyangwl.agile.pay.common.utils.AmountUtils;
import cn.lingyangwl.agile.pay.pay.channel.AbstractRefundService;
import cn.lingyangwl.agile.pay.pay.model.bo.MchAppConfigContext;
import cn.lingyangwl.agile.pay.pay.model.bo.WxServiceWrapper;
import cn.lingyangwl.agile.pay.pay.model.params.wxpay.WxpayIsvsubMchParams;
import cn.lingyangwl.agile.pay.pay.model.rqrs.ChannelRetMsgExt;
import com.alibaba.fastjson2.JSONObject;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 退款接口： 微信官方
 *
 * @author shenguangyang
 */
@Slf4j
@Service
public class WxpayRefundService extends AbstractRefundService {

    @Override
    public IfCodeEnum getIfCode() {
        return IfCodeEnum.WXPAY;
    }

    @Override
    public String preCheck(RefundOrderRQ bizRQ, RefundOrder refundOrder, PayOrder payOrder) {
        return null;
    }

    /**
     * 微信退款接口
     */
    @Override
    public ChannelRetMsgExt refund(RefundOrderRQ bizRQ, RefundOrder refundOrder, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
        try {

            ChannelRetMsgExt channelRetMsgExt = new ChannelRetMsgExt();

            WxServiceWrapper wxServiceWrapper = (WxServiceWrapper) configContextQueryService
                    .getClientWrapper(this.getIfCode(), mchAppConfigContext);
            if (Cs.PAY_IF_VERSION.WX_V3.equals(wxServiceWrapper.getApiVersion())) {   //V3
                // 微信统一下单请求对象
                JSONObject reqJSON = new JSONObject();
                reqJSON.put("out_trade_no", refundOrder.getPayOrderNo());   // 订单号
                reqJSON.put("out_refund_no", refundOrder.getRefundOrderId()); // 退款订单号
                reqJSON.put("notify_url", getNotifyUrl(refundOrder.getRefundOrderId())); // 回调地址

                JSONObject amountJson = new JSONObject();
                amountJson.put("refund", AmountUtils.yuanToFen(refundOrder.getRefundAmount()).longValue());// 退款金额
                amountJson.put("total", AmountUtils.yuanToFen(payOrder.getPayAmount()).longValue());// 订单总金额
                amountJson.put("currency", "CNY");// 币种
                reqJSON.put("amount", amountJson);

                if (mchAppConfigContext.isIsvsubMch()) { // 特约商户
                    WxpayIsvsubMchParams isvsubMchParams = (WxpayIsvsubMchParams) configContextQueryService.queryIsvsubMchParams(mchAppConfigContext.getMchNo(), mchAppConfigContext.getAppId(), getIfCode());
                    reqJSON.put("sub_mchid", isvsubMchParams.getSubMchId());
                }

                JSONObject resultJSON = WxpayV3Util.refundV3(reqJSON, wxServiceWrapper.getWxPayService());
                String status = resultJSON.getString("status");
                if ("SUCCESS".equals(status)) { // 退款成功
                    String refundId = resultJSON.getString("refund_id");
                    channelRetMsgExt.setChannelState(ChannelRetMsgExt.ChannelState.CONFIRM_SUCCESS);
                    channelRetMsgExt.setChannelOrderId(refundId);
                } else if ("PROCESSING".equals(status)) { // 退款处理中
                    String refundId = resultJSON.getString("refund_id");
                    channelRetMsgExt.setChannelState(ChannelRetMsgExt.ChannelState.WAITING);
                    channelRetMsgExt.setChannelOrderId(refundId);
                } else {
                    channelRetMsgExt.setChannelState(ChannelRetMsgExt.ChannelState.CONFIRM_FAIL);
                    channelRetMsgExt.setChannelErrMsg(status);
                }
            } else {
                throw new BizException("不支持的版本");
            }
            return channelRetMsgExt;
        } catch (WxPayException e) {
            log.error("微信退款WxPayException异常: ", e);
            ChannelRetMsgExt channelRetMsgExt = ChannelRetMsgExt.confirmFail();
            WxpayKit.commonSetErrInfo(channelRetMsgExt, e);
            return channelRetMsgExt;

        } catch (Exception e) {
            log.error("微信退款Exception异常: ", e);
            return ChannelRetMsgExt.sysError(e.getMessage());
        }
    }

    /**
     * 微信退款查单接口
     */
    @Override
    public ChannelRetMsgExt query(RefundOrder refundOrder, MchAppConfigContext mchAppConfigContext) throws Exception {
        try {
            ChannelRetMsgExt channelRetMsgExt = new ChannelRetMsgExt();
            WxServiceWrapper wxServiceWrapper = (WxServiceWrapper) configContextQueryService
                    .getClientWrapper(this.getIfCode(), mchAppConfigContext);

            if (Cs.PAY_IF_VERSION.WX_V3.equals(wxServiceWrapper.getApiVersion())) {   //V3
                WxPayService wxPayService = wxServiceWrapper.getWxPayService();
                JSONObject resultJSON = null;
                if (mchAppConfigContext.isIsvsubMch()) {
                    WxpayIsvsubMchParams isvsubMchParams = (WxpayIsvsubMchParams) configContextQueryService.queryIsvsubMchParams(mchAppConfigContext.getMchNo(), mchAppConfigContext.getAppId(), getIfCode());
                    wxPayService.getConfig().setSubMchId(isvsubMchParams.getSubMchId());
                    resultJSON = WxpayV3Util.refundQueryV3Isv(refundOrder.getRefundOrderId(), wxPayService);
                } else {
                    resultJSON = WxpayV3Util.refundQueryV3(refundOrder.getRefundOrderId(), wxPayService);
                }
                String status = resultJSON.getString("status");
                if ("SUCCESS".equals(status)) { // 退款成功
                    channelRetMsgExt.setChannelState(ChannelRetMsgExt.ChannelState.CONFIRM_SUCCESS);
                } else {
                    channelRetMsgExt.setChannelState(ChannelRetMsgExt.ChannelState.WAITING);
                    channelRetMsgExt.setChannelErrMsg(status);
                }
            } else {
                throw new BizException("不支持的版本");
            }
            return channelRetMsgExt;
        } catch (WxPayException e) {
            log.error("微信退款查询WxPayException异常: ", e);
            return ChannelRetMsgExt.sysError(e.getReturnMsg());
        } catch (Exception e) {
            log.error("微信退款查询Exception异常: ", e);
            return ChannelRetMsgExt.sysError(e.getMessage());
        }
    }

}
